use std::fs;
use std::path::Path;
use std::process::Command;

///
/// 查找当前目录下的文件(一直递归往下找, 找到符合以下条件的项目):
/// 如果包含 Cargo.toml 文件, 并且包含了 target 目录, 则认为是一个项目
/// 那么将在此目录执行 cargo clean 命令, 清除 target 目录
/// 忽略掉 以 . 开头的目录, 例如 .git
///
/// English:
/// Find files in the current directory (keep looking down recursively until you find a project that meets the following conditions):
/// If it contains a Cargo.toml file and a target directory, it is considered a project
/// So go to this directory and execute the cargo clean command to clear the target directory
/// Ignore directories starting with ., such as .git
///

fn main() {
    // 程序说明:
    println!("Program description: ");
    // 因为 rust 项目的编译产物 target 目录占用空间较大, 所以写了一个小工具, 用于清理当前程序所在的目录之下, 所有 rust 项目的 target 目录
    println!("Since the target directory of Rust project compilation products takes up a lot of space, I wrote a small tool to clean up the target directories of all Rust projects under the directory where the current program is located.");
    // 当前目录:
    println!(
        "Current directory: {}",
        std::env::current_dir().unwrap().display()
    );
    // ------------ 请确认当前目录是否正确, 点击确认继续 (或者点击 ctrl + c 退出程序)------------
    println!("Please confirm if the current directory is correct, press Enter to continue");
    println!("-- or press ctrl + c to exit the program \n");
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).unwrap();
    if input.trim() != "" {
        // 输入错误, 退出程序
        println!("Input error, exiting program");
        std::thread::sleep(std::time::Duration::from_secs(5));
        return;
    }
    // ------------ start clean projects ------------
    println!("------------ start clean projects ------------");
    clean();
}

fn clean() {
    let current_dir = std::env::current_dir().unwrap();
    find_and_clean_projects(&current_dir);
    // ------------ clean projects done! ------------
    println!("\n------------ clean projects done! ------------");
    std::thread::sleep(std::time::Duration::from_secs(9999999999));
}

fn find_and_clean_projects(dir: &Path) {
    if dir.join("Cargo.toml").exists() && dir.join("target").exists() {
        println!("Cleaning project at {:?}", dir);
        let r = Command::new("cargo").arg("clean").current_dir(dir).status();
        if let Err(e) = r {
            eprintln!("Error: {:?}", e);
        }
    }

    if let Ok(entries) = fs::read_dir(dir) {
        for entry in entries {
            if let Ok(entry) = entry {
                let path = entry.path();
                if path.is_dir() {

                    // 忽略掉 以 . 开头的目录, 例如 .git; 忽略掉 $RECYCLE.BIN
                    let file_name = path
                        .file_name()
                        .map(|x| x.to_str())
                        .unwrap_or_else(|| Some(""))
                        .unwrap_or_else(|| "");
                    if file_name.starts_with(".") || file_name.starts_with("$RECYCLE.") {
                        continue;
                    }

                    find_and_clean_projects(&path);
                }
            }
        }
    }
}
